package org.jeecg.modules.simulator.rooter;

import lombok.Getter;
import lombok.Setter;
import org.jeecg.modules.simulator.factory.train.plan.Train2Parker;
import org.jeecg.modules.simulator.model.MetroTrain;
import org.jeecg.modules.simulator.model.line.Line;
import org.jeecg.modules.simulator.model.line.park.Parker;
import org.jeecg.modules.simulator.model.line.station.station.Station;
import org.jeecg.modules.simulator.model.orbit.OrbitPoint;
import org.jeecg.modules.simulator.model.person.path.PersonPath;
import org.jeecg.modules.simulator.model.train.TrainPhysics;
import org.jeecg.modules.simulator.model.train.timeplan.TrainPlanTable;
import org.jeecg.modules.simulator.util.UnitCache;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @program: simulator-b20240918
 * @description:
 * @author: renzhg
 * @create: 2024-10-10 14:02
 **/
public class NetLineInitializer {
    @Setter
    String sceneCode;
    /**
     * @description: 未分配的列车
     * @author: renzhg
     * @date: 2024/8/30 13:54
     **/
//    @Setter
//    @Getter
//    Map<String, List<MetroTrain>> noAssignMetroTrainMap = new HashMap<>();
    @Setter
    @Getter
    //key:场段ID
    Map<String, List<TrainPlanTable>> trainPlanTableMapByLine = new HashMap<>();
    @Setter
    @Getter
    //按线路Id做的LineRooter
    Map<String, LineRooter> lineRooterMap = new HashMap<>();
    @Setter
    @Getter
    //按线路分的station
    Map<String, List<Station>> linesStationMap = new HashMap<>();
    @Setter
    @Getter
    //stationName,使用站名做Key
    Map<String, Station> stationNameMap = new HashMap<>();
    @Setter
    @Getter
    //总station集合，使用的是stationId,做key
    Map<String, Station> stationMap = new HashMap<>();
    @Setter
    @Getter
    //key:路径序号+首站点名称
    Map<String, PersonPath> personPathMap = new HashMap<>();
    @Setter
    @Getter
    //按线路分配的场段字典
    Map<String, List<Parker>> parkerMap = new HashMap<>();

    @Getter
    //未分配的列车
    Map<String, List<MetroTrain>> metroTrainNoAssigeMap = new HashMap<>();

/**
 * @description:
 * 根据列车在车辆段的数量，创建没有分配的列车，同时把列车放在对应的车辆段。
 * 车型也在这个位置组装进入
 *
 * @author:  renzhg
 * @date:  2024/11/16 10:05
 **/
    public void createNoAssignMetroTrainMap() {
        List<Train2Parker> tplist = UnitCache.globalSceneBaseData.getTplist();
        Map<String, TrainPhysics> trainPhysicsMap = UnitCache.globalSceneBaseData.getTrainPhysicsMap();
        tplist.forEach(e -> {
            List<MetroTrain> metroTrainList = new ArrayList<>();
            for (int i = 0; i < e.getSavers(); i++) {
                MetroTrain metroTrain = new MetroTrain();
                metroTrain.setGroupId(UUID.randomUUID().toString());

                metroTrain.setTrainPhysics(trainPhysicsMap.get("A型车"));
                metroTrainList.add(metroTrain);
            }
            metroTrainNoAssigeMap.put(e.getParkerId(), metroTrainList);
        });


    }

    /**
     * @description: 线路组装
     * @author: renzhg
     * @date: 2024/9/10 17:49
     **/
//数据LineRooter装配
    public Map<String, Line>  assignLineRooterData() {
        Map<String, Line> lineMap = UnitCache.globalSceneBaseData.getLineFilterMap();
//        infoDataFactory.loadData();//加载时刻表
        //时刻表，轨道分配
        lineAssign(lineMap, trainPlanTableMapByLine);
        return  lineMap;


    }


    /**
     * @description: 线路组装
     * 1、生成一个名字的站点字典
     * 2、生成一个id的站点字典
     * 3、生成上下行轨道轨道
     * 4、生成停车场--停车场中装配了列车数据
     * 5、组装到线路数据中
     * 6、分配路径到每个站点
     * 7、分配轨道到车站
     * @author: renzhg
     * @date: 2024/9/5 10:11
     **/
    private void lineAssign(Map<String, Line> lineMap, Map<String, List<TrainPlanTable>> trainPlanTableMapByLine) {
        for (Map.Entry<String, Line> entry : lineMap.entrySet()) {
            String lineKey = entry.getKey();
            Line line = entry.getValue();
            LineRooter lineRooter = new LineRooter();
            // 初始化 LineRooter 对象
            assignStationsAndOrbitPoints(lineRooter, lineKey, line);
            if (lineRooter.isLoaderdata()) {
                //时刻表分配
                processTrainPlanTables(lineRooter, trainPlanTableMapByLine, lineKey);
                lineRooterMap.put(lineKey, lineRooter);
            }
            // 分配停车场及给停车场分配列车
            assigePark(lineKey, line, lineRooter.getStationStionIdMap());
            // 处理 TrainPlanTable


        }
    }

    /**
     * @description: 分配站点和轨道点
     * @author: renzhg
     * @date: 2024/9/5 18:12
     **/
    private void assignStationsAndOrbitPoints(LineRooter lineRooter, String lineKey, Line line) {
        if (!linesStationMap.containsKey(lineKey)) {
            return;
        }
        setStationNameMapAndIdMap(lineRooter, lineKey);
        // 轨道
//        List<OrbitPoint> orbitPointList = dataLoader.getOrbitPointpMap().get(lineKey);
        assignOrbitPoint2Line(lineRooter, lineKey, line);
        // 给车站分配人员走行路径，就是所有以这个车站为起始站的路径
        assingeStation();
        //路径装配完成后设置标志位
        lineRooter.setLoaderdata(true);
    }


    //分配轨道数据给每条线路，就是给每条线给上下轨道数据
    private void assignOrbitPoint2Line(LineRooter lineRooter, String lineKey, Line line) {
        List<OrbitPoint> orbitPointList = UnitCache.globalSceneBaseData.getOrbitFilterPointListMap().get(lineKey);
        // 设置 Line 和 Line ID
        lineRooter.setLine(line);
//        lineRooter.setLineId(lineKey);
        // 初始化线路上下行轨道数据
        lineRooter.assingObtiPath(orbitPointList);
    }


    /**
     * @param lineRooter: 线路根对象
     * @param lineKey:    线路ID
     * @description: 设置站点名字和ID的Map
     * @return: java.util.Map<java.lang.String, com.renzhg.gp.gp.simulator.model.line.station.station.Station>
     * @date: 2024/9/11 16:42
     **/
    private void setStationNameMapAndIdMap(LineRooter lineRooter, String lineKey) {
        List<Station> lineStations = linesStationMap.get(lineKey);
        // 创建以名字和ID为键的 Station Map
        Map<String, Station> lsMap = lineStations.stream()
                .collect(Collectors.toMap(Station::getName, station -> station));
        Map<String, Station> lsMap2 = lineStations.stream()
                .collect(Collectors.toMap(Station::getId, station -> station));
        stationNameMap.putAll(lsMap);
        // 设置 Station Map
        lineRooter.setStationInThisLineMap(lsMap);
        lineRooter.setStationStionIdMap(lsMap2);

    }

    /**
     * @description: 给车站分配人员走行路径，就是所有以这个车站为起始站的路径
     * @author: renzhg
     * @date: 2024/9/11 16:42
     **/
    public void assingeStation() {
        stationMap.forEach((k, v) -> {
            Map<String, PersonPath> personPathMap1 = new HashMap<>();
            personPathMap.forEach((pk, pv) -> {
                String startStationName = pk.split("_")[1];
                String pathIndex = pk.split("_")[0];
                if (v.getName().equals(startStationName)) {
                    personPathMap1.put(pathIndex, pv);
                }
            });
            v.setPersonPathMap(personPathMap1);

        });


    }


    /**
     * @description: 处理时刻表
     * @author: renzhg
     * @date: 2024/9/5 18:13
     **/
    private void processTrainPlanTables(LineRooter lineRooter, Map<String, List<TrainPlanTable>> trainPlanTableMapByLine, String lineKey) {
        if (!trainPlanTableMapByLine.containsKey(lineKey)) {
            return;
        }
        List<TrainPlanTable> trainPlanTableList = trainPlanTableMapByLine.get(lineKey);
        /**
         * @description: 把到站ID赋值给时刻表，在parker分配时间的时候会用到
         *
         * @author: renzhg
         * @date: 2024/9/5 18:22
         **/
//        for (int i = 0; i < trainPlanTableList.size(); i++) {
//            TrainPlanTable trainPlanTable = trainPlanTableList.get(i);
//            String stationName = trainPlanTable.getArriveStaionName();
//
//
//            Station station = lineRooter.getStationInThisLineMap().get(stationName);
//            System.out.println(station.getId());
//            trainPlanTable.setArriveStaionName(stationName);
//            System.out.println("stationName:" + stationName);
//            trainPlanTable.setArrivateStaionId(station.getId());
//
//        }

        if (trainPlanTableList != null) {
            // 按 TrainId 和 TrainNum 分组
            Map<String, List<TrainPlanTable>> trainPlanTableMap = trainPlanTableList.stream()
                    .collect(Collectors.groupingBy(o -> o.getTrainId() + "-" + o.getTrainNum()));
            lineRooter.setTrainPlanTableMap(trainPlanTableMap);
        }
    }

    /**
     * @description: 分配停车场及给停车场分配列车
     * @author: renzhg
     * @date: 2024/9/4 13:42
     **/
    private void assigePark(String k, Line v, Map<String, Station> stationMap) {
        //分配车给停车场
        if(!metroTrainNoAssigeMap.isEmpty()){
            parkerMap.get(k).forEach(p -> {
                List<MetroTrain> metroTrains = metroTrainNoAssigeMap.get(p.getId());
                p.setUpOut(stationMap.get(p.getUpOutStationId()));
                p.setDownOut(stationMap.get(p.getDownOutStationId()));
                LineRooter lineRooter = lineRooterMap.get(p.getLineId());
                String ls=metroTrains.get(0).getTrainPhysics().getTrainName();
                System.out.println(ls);
                lineRooter.trainManager.setTrainType(ls);
                Map<String, MetroTrain> aa = metroTrains.stream().collect(Collectors.toMap(MetroTrain::getGroupId, m -> m));
                p.setNotOnlineTrainMap(aa);
            });
        }

        List<Parker> parkers = parkerMap.get(k);
        //分配停车场给线路
        Map<String, Parker> parkmap = parkers.stream().collect(Collectors.toMap(Parker::getName, p -> p));
        v.setParkerMap(parkmap);
        v.initParkObit();
    }

}
